package com.txy.domain.strategy.service.rule.tree.factory.engine;

import com.alibaba.fastjson.JSON;
import com.txy.domain.strategy.model.vo.RuleLogicCheckTypeVO;
import com.txy.domain.strategy.model.vo.RuleTreeNodeLineVO;
import com.txy.domain.strategy.model.vo.RuleTreeNodeVO;
import com.txy.domain.strategy.model.vo.RuleTreeVO;
import com.txy.domain.strategy.service.rule.tree.ILogicTreeNode;
import com.txy.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;

@Slf4j
public class DecisionTreeEngine implements IDecisionTreeEngine {
    private final Map<String, ILogicTreeNode> logicTreeGroup;

    private final RuleTreeVO ruleTreeVO;

    public DecisionTreeEngine(Map<String, ILogicTreeNode> logicTreeGroup, RuleTreeVO ruleTreeVO) {
        this.logicTreeGroup = logicTreeGroup;
        this.ruleTreeVO = ruleTreeVO;
    }


    @Override
    public DefaultTreeFactory.AwardResClass process(Long strategyId, String userId, Integer awardId) {
        String treeRootRuleNode = ruleTreeVO.getTreeRootRuleNode(); // 根节点
        Map<String, RuleTreeNodeVO> treeNodeMap = ruleTreeVO.getTreeNodeMap(); // 决策树子节点map

        RuleTreeNodeVO ruleTreeNodeVO = treeNodeMap.get(treeRootRuleNode); // treeNode节点

        DefaultTreeFactory.AwardResClass resClass = null;

        while (treeRootRuleNode != null) {
            ILogicTreeNode iLogicTreeNode = logicTreeGroup.get(ruleTreeNodeVO.getRuleKey());
            DefaultTreeFactory.DecisionEngineRes logic = iLogicTreeNode.logic(strategyId, userId, awardId, ruleTreeNodeVO.getRuleValue());

            RuleLogicCheckTypeVO ruleLogicCheckTypeVO = logic.getRuleLogicCheckTypeVO();
            resClass = logic.getAwardResClass();

            treeRootRuleNode = nextTreeNode(ruleLogicCheckTypeVO, ruleTreeNodeVO.getTreeNodeLineVOList());
            ruleTreeNodeVO = treeNodeMap.get(treeRootRuleNode);
        }
        return resClass;

    }

    private String nextTreeNode(RuleLogicCheckTypeVO ruleLogicCheckTypeVO, List<RuleTreeNodeLineVO> treeNodeLineVOList) {
        if (treeNodeLineVOList == null || treeNodeLineVOList.isEmpty()) {
            return null;
        }
        for (RuleTreeNodeLineVO ruleTreeNodeLineVO : treeNodeLineVOList) {
            if (decisionEqual(ruleLogicCheckTypeVO.getCode(), ruleTreeNodeLineVO)) {
                return ruleTreeNodeLineVO.getRuleNodeTo();
            }
        }
        return null;
    }

    private boolean decisionEqual(String code, RuleTreeNodeLineVO ruleTreeNodeLineVO) {
        switch (ruleTreeNodeLineVO.getRuleLimitType()) {
            case EQUAL:
                return code.equals(ruleTreeNodeLineVO.getRuleLimitValue().getCode());
            default:
                break;
        }
        return false;
    }
}
